﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using RayTracer;
using System.Runtime.InteropServices;
using System.Drawing;
using Cloo;

namespace GPURayTracer
{
    static class Program
    {
        #region DLLImports
        [DllImport("kernel32.dll")]
        static extern bool AllocConsole();

        [DllImport("kernel32.dll")]
        static extern bool FreeConsole();
        #endregion DLLImports

        #region Attribute
        public static string[] Arguments;
        public static RayTracer.RayTracer RayTracer;
        public static MainForm MainForm;
        #endregion Attribute

        #region Methoden
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        /// <param name="args">Die der Anwendung übergebenen Parameter.</param>
        [STAThread]
        static void Main(string[] args)
        {
            Arguments = args;
            bool runningWin32NT = (Environment.OSVersion.Platform == PlatformID.Win32NT);
            bool consoleAllocated = false;
            try
            {
                if (runningWin32NT) consoleAllocated = AllocConsole();
                Console.Title = "Raytracer Console";
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                MainForm = new MainForm();
                Application.Run(MainForm);
            }
            catch { }
            if (consoleAllocated) FreeConsole();
        }

        /// <summary>
        /// Berechnet die geschätzte mögliche Maximalauflösung.
        /// Dies hängt natürlich immer noch etwas von den Objekten und insbesondere Lichtern ab.
        /// (Zudem muss die Auflösung nicht quadratisch sein.)
        /// </summary>
        /// <param name="device">Das Gerät.</param>
        /// <param name="maxDepth">Die max. Rekursionstiefe.</param>
        /// <returns>Die max. Auflösung.</returns>
        public static Size GetGuessedMaxResolution(ComputeDevice device, int maxDepth)
        {
            float LIGHTSCOUNT = 10; // Annahme über durchschnittliche Lichteranzahl.

            long mem = 0;
            long maxBuffer = 0;
            try { mem = device.GlobalMemorySize; }
            catch { }
            try { maxBuffer = device.MaxMemoryAllocationSize; }
            catch { }

            long memPerPixel = global::RayTracer.RayTracer.GetMinRequiredMemory(maxDepth, new Size(1, 1));
            long x = 4;
            long y = 3;
            while (x * y * memPerPixel <= mem && x * y * 4 * 4 * LIGHTSCOUNT <= maxBuffer)
            {
                x += 4;
                y += 3;
            }
            return new Size((int)x, (int)y);
        }
        #endregion Methoden
    }
}
